﻿Imports System
Imports System.Collections
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
Imports System.Collections.Specialized
Imports System.ComponentModel.Design
Imports System.ComponentModel.Design.Serialization
Imports System.Configuration
Imports System.Diagnostics
Imports System.Globalization
Imports System.IO
Imports System.Reflection
Imports System.Runtime.CompilerServices
Imports System.Threading
Imports System.Workflow.ComponentModel
Imports System.Workflow.ComponentModel.Compiler
Imports System.Workflow.ComponentModel.Serialization
Imports System.Workflow.Runtime.Configuration
Imports System.Workflow.Runtime.DebugEngine
Imports System.Workflow.Runtime.Hosting
Imports System.Workflow.Runtime.Tracking
Imports System.Xml

Namespace System.Workflow.Runtime
    Public Class WorkflowRuntime
        Implements IServiceProvider, IDisposable
        ' Events
        Public Custom Event ServicesExceptionNotHandled As EventHandler([Of] ServicesExceptionNotHandledEventArgs)
        Public Custom Event Started As EventHandler([Of] WorkflowRuntimeEventArgs)
        Public Custom Event Stopped As EventHandler([Of] WorkflowRuntimeEventArgs)
        Public Custom Event WorkflowAborted As EventHandler([Of] WorkflowEventArgs)
        Public Custom Event WorkflowCompleted As EventHandler([Of] WorkflowCompletedEventArgs)
        Public Custom Event WorkflowCreated As EventHandler([Of] WorkflowEventArgs)
        Friend Custom Event WorkflowDynamicallyChanged As EventHandler([Of] WorkflowEventArgs)
        Friend Custom Event WorkflowExecutorInitializing As EventHandler([Of] WorkflowExecutorInitializingEventArgs)
        Public Custom Event WorkflowIdled As EventHandler([Of] WorkflowEventArgs)
        Public Custom Event WorkflowLoaded As EventHandler([Of] WorkflowEventArgs)
        Public Custom Event WorkflowPersisted As EventHandler([Of] WorkflowEventArgs)
        Public Custom Event WorkflowResumed As EventHandler([Of] WorkflowEventArgs)
        Public Custom Event WorkflowStarted As EventHandler([Of] WorkflowEventArgs)
        Public Custom Event WorkflowSuspended As EventHandler([Of] WorkflowSuspendedEventArgs)
        Public Custom Event WorkflowTerminated As EventHandler([Of] WorkflowTerminatedEventArgs)
        Public Custom Event WorkflowUnloaded As EventHandler([Of] WorkflowEventArgs)

        ' Methods
        Shared Sub New()
            AddHandler Activity.ActivityResolve, New ActivityResolveEventHandler(AddressOf WorkflowRuntime.OnActivityDefinitionResolve)
            AddHandler Activity.WorkflowChangeActionsResolve, New WorkflowChangeActionsResolveEventHandler(AddressOf WorkflowRuntime.OnWorkflowChangeActionsResolve)
        End Sub

        Public Sub New()
            Me._servicesLock = New Object
            Me._startStopLock = New Object
            Me._uid = Guid.NewGuid
            Me.disableWorkflowDebugging = New BooleanSwitch("DisableWorkflowDebugging", "Disables workflow debugging in host")
            Me._trackingFactory = New TrackingListenerFactory
            Me._services = New Dictionary([Of] Type, List([Of] Object))
            Me.PrivateInitialize(Nothing)
        End Sub

        Public Sub New(ByVal configSectionName As String)
            Me._servicesLock = New Object
            Me._startStopLock = New Object
            Me._uid = Guid.NewGuid
            Me.disableWorkflowDebugging = New BooleanSwitch("DisableWorkflowDebugging", "Disables workflow debugging in host")
            Me._trackingFactory = New TrackingListenerFactory
            Me._services = New Dictionary([Of] Type, List([Of] Object))
            If (configSectionName Is Nothing) Then
                Throw New ArgumentNullException("configSectionName")
            End If
            Dim settings As WorkflowRuntimeSection = [TryCast](ConfigurationManager.GetSection(configSectionName),WorkflowRuntimeSection)
            If (settings Is Nothing) Then
                Throw New ArgumentException(String.Format(CultureInfo.CurrentCulture, ExecutionStringManager.ConfigurationSectionNotFound, New Object() { configSectionName }), "configSectionName")
            End If
            Me.PrivateInitialize(settings)
        End Sub

        Public Sub New(ByVal settings As WorkflowRuntimeSection)
            Me._servicesLock = New Object
            Me._startStopLock = New Object
            Me._uid = Guid.NewGuid
            Me.disableWorkflowDebugging = New BooleanSwitch("DisableWorkflowDebugging", "Disables workflow debugging in host")
            Me._trackingFactory = New TrackingListenerFactory
            Me._services = New Dictionary([Of] Type, List([Of] Object))
            If (settings Is Nothing) Then
                Throw New ArgumentNullException("settings")
            End If
            Me.PrivateInitialize(settings)
        End Sub

        Private Sub _OnServiceEvent(ByVal sched As WorkflowExecutor, ByVal unregister As Boolean, ByVal handler As EventHandler([Of] WorkflowEventArgs))
            Try 
                Dim e As New WorkflowEventArgs(sched.WorkflowInstance)
                If (Not handler Is Nothing) Then
                    handler.Invoke(Me, e)
                End If
            Catch exception1 As Exception
                WorkflowTrace.Host.TraceEvent(TraceEventType.Error, 0, "WorkflowRuntime:OnService Event threw an exception.")
                Throw
            Finally
                If unregister Then
                    Me._unRegister(sched)
                End If
            End Try
        End Sub

        Private Sub _unRegister(ByVal executor As WorkflowExecutor)
            Me.TryRemoveWorkflowExecutor(executor.InstanceId, executor)
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime::_removeInstance, instance:{0}, hc:{1}", New Object() { executor.InstanceId, executor.GetHashCode })
            WorkflowTrace.Runtime.Flush
            WorkflowTrace.Tracking.Flush
            WorkflowTrace.Host.Flush
        End Sub

        Public Sub AddService(ByVal service As Object)
            If (service Is Nothing) Then
                Throw New ArgumentNullException("service")
            End If
            Me.VerifyInternalState
            [Using] New EventContext(New Object(0  - 1) {})
                SyncLock Me._startStopLock
                    Me.AddServiceImpl(service)
                End SyncLock
            End [Using]
        End Sub

        Private Sub AddServiceFromSettings(ByVal serviceSettings As WorkflowRuntimeServiceElement)
            Dim service As Object = Nothing
            Dim type As Type = Type.GetType(serviceSettings.Type, True)
            Dim info As ConstructorInfo = Nothing
            Dim info2 As ConstructorInfo = Nothing
            Dim info3 As ConstructorInfo = Nothing
            Dim info4 As ConstructorInfo
            For Each info4 In type.GetConstructors
                Dim parameters As ParameterInfo() = info4.GetParameters
                If (parameters.Length = 1) Then
                    If GetType(IServiceProvider).IsAssignableFrom(parameters(0).ParameterType) Then
                        info2 = info4
                    ElseIf GetType(NameValueCollection).IsAssignableFrom(parameters(0).ParameterType) Then
                        info3 = info4
                    End If
                ElseIf (((parameters.Length = 2) AndAlso GetType(IServiceProvider).IsAssignableFrom(parameters(0).ParameterType)) AndAlso GetType(NameValueCollection).IsAssignableFrom(parameters(1).ParameterType)) Then
                    info = info4
                    Exit For
                End If
            Next
            If (Not info Is Nothing) Then
                service = info.Invoke(New Object() { Me, serviceSettings.Parameters })
            ElseIf (Not info2 Is Nothing) Then
                service = info2.Invoke(New Object() { Me })
            ElseIf (Not info3 Is Nothing) Then
                service = info3.Invoke(New Object() { serviceSettings.Parameters })
            Else
                service = Activator.CreateInstance(type)
            End If
            Me.AddServiceImpl(service)
        End Sub

        Private Sub AddServiceImpl(ByVal service As Object)
            SyncLock Me._servicesLock
                If Me.GetAllServices(service.GetType).Contains(service) Then
                    Throw New InvalidOperationException(ExecutionStringManager.CantAddServiceTwice)
                End If
                If (Me._startedServices AndAlso Me.IsCoreService(service)) Then
                    Throw New InvalidOperationException(ExecutionStringManager.CantChangeImmutableContainer)
                End If
                Dim key As Type = service.GetType
                Dim type2 As Type
                For Each type2 In key.GetInterfaces
                    Dim list As List([Of] Object)
                    If Me._services.ContainsKey(type2) Then
                        list = Me._services.Item(type2)
                    Else
                        list = New List([Of] Object)
                        Me._services.Add(type2, list)
                    End If
                    list.Add(service)
                Next
                Do While (Not key Is Nothing)
                    Dim list2 As List([Of] Object) = Nothing
                    If Me._services.ContainsKey(key) Then
                        list2 = Me._services.Item(key)
                    Else
                        list2 = New List([Of] Object)
                        Me._services.Add(key, list2)
                    End If
                    list2.Add(service)
                    key = key.BaseType
                Loop
            End SyncLock
            Dim service2 As WorkflowRuntimeService = [TryCast](service,WorkflowRuntimeService)
            If (Not service2 Is Nothing) Then
                service2.SetRuntime(Me)
                If Me._startedServices Then
                    service2.Start
                End If
            End If
        End Sub

        Friend Shared Sub ClearTrackingProfileCache()
            SyncLock WorkflowRuntime._runtimesLock
                Dim reference As WeakReference
                For Each reference In WorkflowRuntime._runtimes.Values
                    Dim target As WorkflowRuntime = [TryCast](reference.Target,WorkflowRuntime)
                    If (((Not target Is Nothing) AndAlso (Not target.TrackingListenerFactory Is Nothing)) AndAlso (Not target.TrackingListenerFactory.TrackingProfileManager Is Nothing)) Then
                        target.TrackingListenerFactory.TrackingProfileManager.ClearCacheImpl
                    End If
                Next
            End SyncLock
        End Sub

        Private Function CreateCompletedEventArgs(ByVal exec As WorkflowExecutor) As WorkflowCompletedEventArgs
            Dim args As New WorkflowCompletedEventArgs(exec.WorkflowInstance, exec.WorkflowDefinition)
            Dim info As PropertyInfo
            For Each info In Me._workflowDefinitionDispenser.GetOutputParameters(exec.RootActivity)
                args.OutputParameters.Add(info.Name, info.GetValue(exec.RootActivity, Nothing))
            Next
            Return args
        End Function

        Friend Shared Function CreateTypeProvider(ByVal rootActivity As Activity) As TypeProvider
            Dim provider As New TypeProvider(Nothing)
            Dim type As Type = rootActivity.GetType
            provider.SetLocalAssembly(type.Assembly)
            provider.AddAssembly(type.Assembly)
            Dim name As AssemblyName
            For Each name In type.Assembly.GetReferencedAssemblies
                Dim assembly As Assembly = Nothing
                Try 
                    [assembly] = Assembly.Load(name)
                    If (Not [assembly] Is Nothing) Then
                        provider.AddAssembly([assembly])
                    End If
                Catch obj1 As Object
                End Try
                If (([assembly] Is Nothing) AndAlso (Not name.CodeBase Is Nothing)) Then
                    provider.AddAssemblyReference(name.CodeBase)
                End If
            Next
            Return provider
        End Function

        Public Function CreateWorkflow(ByVal workflowType As Type) As WorkflowInstance
            If (workflowType Is Nothing) Then
                Throw New ArgumentNullException("workflowType")
            End If
            If Not GetType(Activity).IsAssignableFrom(workflowType) Then
                Throw New ArgumentException(ExecutionStringManager.TypeMustImplementRootActivity, "workflowType")
            End If
            Me.VerifyInternalState
            Return Me.InternalCreateWorkflow(New CreationContext(workflowType, Nothing, Nothing, Nothing), Guid.NewGuid)
        End Function

        Public Function CreateWorkflow(ByVal workflowDefinitionReader As XmlReader) As WorkflowInstance
            If (workflowDefinitionReader Is Nothing) Then
                Throw New ArgumentNullException("workflowDefinitionReader")
            End If
            Me.VerifyInternalState
            Return Me.CreateWorkflow(workflowDefinitionReader, Nothing, Nothing)
        End Function

        Public Function CreateWorkflow(ByVal workflowType As Type, ByVal namedArgumentValues As Dictionary([Of] String, Object)) As WorkflowInstance
            Return Me.CreateWorkflow(workflowType, namedArgumentValues, Guid.NewGuid)
        End Function

        Public Function CreateWorkflow(ByVal workflowType As Type, ByVal namedArgumentValues As Dictionary([Of] String, Object), ByVal instanceId As Guid) As WorkflowInstance
            If (workflowType Is Nothing) Then
                Throw New ArgumentNullException("workflowType")
            End If
            If Not GetType(Activity).IsAssignableFrom(workflowType) Then
                Throw New ArgumentException(ExecutionStringManager.TypeMustImplementRootActivity, "workflowType")
            End If
            Me.VerifyInternalState
            Return Me.InternalCreateWorkflow(New CreationContext(workflowType, Nothing, Nothing, namedArgumentValues), instanceId)
        End Function

        Public Function CreateWorkflow(ByVal workflowDefinitionReader As XmlReader, ByVal rulesReader As XmlReader, ByVal namedArgumentValues As Dictionary([Of] String, Object)) As WorkflowInstance
            Return Me.CreateWorkflow(workflowDefinitionReader, rulesReader, namedArgumentValues, Guid.NewGuid)
        End Function

        Public Function CreateWorkflow(ByVal workflowDefinitionReader As XmlReader, ByVal rulesReader As XmlReader, ByVal namedArgumentValues As Dictionary([Of] String, Object), ByVal instanceId As Guid) As WorkflowInstance
            If (workflowDefinitionReader Is Nothing) Then
                Throw New ArgumentNullException("workflowDefinitionReader")
            End If
            Me.VerifyInternalState
            Dim context As New CreationContext(workflowDefinitionReader, rulesReader, namedArgumentValues)
            Return Me.InternalCreateWorkflow(context, instanceId)
        End Function

        Public Sub Dispose()
            SyncLock Me._startStopLock
                If Not Me._disposed Then
                    If (Not Me.debugController Is Nothing) Then
                        Me.debugController.Close
                    End If
                    Me._workflowDefinitionDispenser.Dispose
                    Me._startedServices = False
                    Me._disposed = True
                End If
            End SyncLock
            SyncLock WorkflowRuntime._runtimesLock
                If WorkflowRuntime._runtimes.ContainsKey(Me._uid) Then
                    WorkflowRuntime._runtimes.Remove(Me._uid)
                End If
            End SyncLock
        End Sub

        Private Sub DynamicUpdateCommit(ByVal sender As Object, ByVal e As DynamicUpdateEventArgs)
            If (sender Is Nothing) Then
                Throw New ArgumentNullException("sender")
            End If
            If Not GetType(WorkflowExecutor).IsInstanceOfType(sender) Then
                Throw New ArgumentException(String.Format(CultureInfo.CurrentCulture, ExecutionStringManager.InvalidArgumentType, New Object() { "sender", GetType(WorkflowExecutor).ToString }))
            End If
            Dim schedule As WorkflowExecutor = DirectCast(sender, WorkflowExecutor)
            Me.OnScheduleDynamicallyChanged(schedule)
        End Sub

        Public Function GetAllServices([Of] T)() As ReadOnlyCollection([Of] T)
            Me.VerifyInternalState
            Dim list As New List([Of] T)
            Dim local As T
            For Each local In Me.GetAllServices(GetType(T))
                list.Add(local)
            Next
            Return New ReadOnlyCollection([Of] T)(list)
        End Function

        Public Function GetAllServices(ByVal serviceType As Type) As ReadOnlyCollection([Of] Object)
            If (serviceType Is Nothing) Then
                Throw New ArgumentNullException("serviceType")
            End If
            Me.VerifyInternalState
            SyncLock Me._servicesLock
                Dim list As New List([Of] Object)
                If Me._services.ContainsKey(serviceType) Then
                    list.AddRange(Me._services.Item(serviceType))
                End If
                Return New ReadOnlyCollection([Of] Object)(list)
            End SyncLock
        End Function

        Public Function GetLoadedWorkflows() As ReadOnlyCollection([Of] WorkflowInstance)
            Me.VerifyInternalState
            Dim list As New List([Of] WorkflowInstance)
            Dim executor As WorkflowExecutor
            For Each executor In Me.GetWorkflowExecutors
                list.Add(executor.WorkflowInstance)
            Next
            Return list.AsReadOnly
        End Function

        Public Function GetService([Of] T)() As T
            Me.VerifyInternalState
            Return DirectCast(Me.GetService(GetType(T)), T)
        End Function

        Public Function GetService(ByVal serviceType As Type) As Object
            If (serviceType Is Nothing) Then
                Throw New ArgumentNullException("serviceType")
            End If
            Me.VerifyInternalState
            SyncLock Me._servicesLock
                Dim obj2 As Object = Nothing
                If Me._services.ContainsKey(serviceType) Then
                    Dim list As List([Of] Object) = Me._services.Item(serviceType)
                    If (list.Count > 1) Then
                        Throw New InvalidOperationException(String.Format(CultureInfo.CurrentCulture, ExecutionStringManager.MoreThanOneService, New Object() { serviceType.ToString }))
                    End If
                    If (list.Count = 1) Then
                        obj2 = list.Item(0)
                    End If
                End If
                Return obj2
            End SyncLock
        End Function

        Public Function GetWorkflow(ByVal instanceId As Guid) As WorkflowInstance
            If (instanceId = Guid.Empty) Then
                Throw New ArgumentException(String.Format(CultureInfo.CurrentCulture, ExecutionStringManager.CantBeEmptyGuid, New Object() { "instanceId" }))
            End If
            Me.VerifyInternalState
            If Not Me.IsStarted Then
                Throw New InvalidOperationException(ExecutionStringManager.WorkflowRuntimeNotStarted)
            End If
            Return Me.Load(instanceId, Nothing, Nothing).WorkflowInstance
        End Function

        Friend Function GetWorkflowDefinition(ByVal workflowType As Type) As Activity
            If (workflowType Is Nothing) Then
                Throw New ArgumentNullException("workflowType")
            End If
            Me.VerifyInternalState
            Return Me._workflowDefinitionDispenser.GetRootActivity(workflowType, False, True)
        End Function

        Private Function GetWorkflowExecutor(ByVal instanceId As Guid, ByVal context As CreationContext) As WorkflowExecutor
            Dim executor2 As WorkflowExecutor
            Try 
                WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime dispensing resource, instanceId: {0}", New Object() { instanceId })
                Dim executor As WorkflowExecutor = Me.Load(instanceId, context, Nothing)
                WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime dispensing resource instanceId: {0}, hc: {1}", New Object() { instanceId, executor.GetHashCode })
                executor2 = executor
            Catch exception1 As OutOfMemoryException
                WorkflowTrace.Host.TraceEvent(TraceEventType.Error, 0, "WorkflowRuntime dispensing resource, can't create service due to OOM!(1), instance, {0}", New Object() { instanceId })
                Throw
            Catch exception As Exception
                WorkflowTrace.Host.TraceEvent(TraceEventType.Error, 0, "WorkflowRuntime dispensing resource, can't create service due to unexpected exception!(2), instance, {0}, exception, {1}", New Object() { instanceId, exception })
                Throw
            End Try
            Return executor2
        End Function

        Private Function GetWorkflowExecutors() As IList([Of] WorkflowExecutor)
            Dim list As New List([Of] WorkflowExecutor)
            Dim dictionary As Dictionary([Of] Guid, WorkflowExecutor)
            For Each dictionary In Me.workflowExecutors
                SyncLock dictionary
                    Dim executor As WorkflowExecutor
                    For Each executor In dictionary.Values
                        If ((Not executor Is Nothing) AndAlso executor.IsInstanceValid) Then
                            list.Add(executor)
                        End If
                    Next
                    [Continue] For
                End SyncLock
            Next
            Return list
        End Function

        Private Function InitializeExecutor(ByVal instanceId As Guid, ByVal context As CreationContext, ByVal executor As WorkflowExecutor, ByVal workflowInstance As WorkflowInstance) As Activity
            Dim rootActivity As Activity = Nothing
            If ((Not context Is Nothing) AndAlso context.IsActivation) Then
                Dim activity2 As Activity = Nothing
                Dim str As String = Nothing
                Dim rulesText As String = Nothing
                If (Not context.Type Is Nothing) Then
                    activity2 = Me._workflowDefinitionDispenser.GetRootActivity(context.Type, False, True)
                    rootActivity = Me._workflowDefinitionDispenser.GetRootActivity(context.Type, True, False)
                ElseIf (Not context.XomlReader Is Nothing) Then
                    Try 
                        context.XomlReader.MoveToContent
                        Do While (Not context.XomlReader.EOF AndAlso Not context.XomlReader.IsStartElement)
                            context.XomlReader.Read
                        Loop
                        str = context.XomlReader.ReadOuterXml
                        If (Not context.RulesReader Is Nothing) Then
                            context.RulesReader.MoveToContent
                            Do While (Not context.RulesReader.EOF AndAlso Not context.RulesReader.IsStartElement)
                                context.RulesReader.Read
                            Loop
                            rulesText = context.RulesReader.ReadOuterXml
                        End If
                    Catch exception As Exception
                        Throw New ArgumentException(ExecutionStringManager.InvalidXAML, exception)
                    End Try
                    If String.IsNullOrEmpty(str) Then
                        Throw New ArgumentException(ExecutionStringManager.InvalidXAML)
                    End If
                    activity2 = Me._workflowDefinitionDispenser.GetRootActivity(str, rulesText, False, True)
                    rootActivity = Me._workflowDefinitionDispenser.GetRootActivity(str, rulesText, True, False)
                End If
                rootActivity.SetValue(Activity.WorkflowDefinitionProperty, activity2)
                WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, ("Creating instance " & instanceId.ToString))
                context.Created = True
                executor.Initialize(rootActivity, context.InvokerExecutor, context.InvokeActivityID, instanceId, context.Args, workflowInstance)
                Return rootActivity
            End If
            If (Me.WorkflowPersistenceService Is Nothing) Then
                Dim message As String = String.Format(CultureInfo.CurrentCulture, ExecutionStringManager.MissingPersistenceService, New Object() { instanceId })
                WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 0, message)
                Throw New InvalidOperationException(message)
            End If
            [Using] New RuntimeEnvironment(Me)
                rootActivity = Me.WorkflowPersistenceService.LoadWorkflowInstanceState(instanceId)
            End [Using]
            If (rootActivity Is Nothing) Then
                Throw New InvalidOperationException(String.Format(Thread.CurrentThread.CurrentCulture, ExecutionStringManager.InstanceNotFound, New Object() { instanceId }))
            End If
            executor.Reload(rootActivity, workflowInstance)
            Return rootActivity
        End Function

        Friend Function InternalCreateWorkflow(ByVal context As CreationContext, ByVal instanceId As Guid) As WorkflowInstance
            [Using] New WorkflowTraceTransfer(instanceId)
                Me.VerifyInternalState
                If Not Me.IsStarted Then
                    Me.StartRuntime
                End If
                Dim workflowExecutor As WorkflowExecutor = Me.GetWorkflowExecutor(instanceId, context)
                If Not context.Created Then
                    Throw New InvalidOperationException(ExecutionStringManager.WorkflowWithIdAlreadyExists)
                End If
                Return workflowExecutor.WorkflowInstance
            End [Using]
        End Function

        Private Function IsCoreService(ByVal service As Object) As Boolean
            Return (((TypeOf service Is WorkflowSchedulerService OrElse TypeOf service Is WorkflowPersistenceService) OrElse (TypeOf service Is TrackingService OrElse TypeOf service Is WorkflowCommitWorkBatchService)) OrElse TypeOf service Is WorkflowLoaderService)
        End Function

        Friend Function Load(ByVal instance As WorkflowInstance) As WorkflowExecutor
            Return Me.Load(instance.InstanceId, Nothing, instance)
        End Function

        Friend Function Load(ByVal key As Guid, ByVal context As CreationContext, ByVal workflowInstance As WorkflowInstance) As WorkflowExecutor
            Dim executor As WorkflowExecutor
            Dim dictionary As Dictionary([Of] Guid, WorkflowExecutor) = Me.workflowExecutors.Item(key)
            SyncLock dictionary
                If Not Me.IsStarted Then
                    Throw New InvalidOperationException(ExecutionStringManager.WorkflowRuntimeNotStarted)
                End If
                If (dictionary.TryGetValue(key, executor) AndAlso executor.IsInstanceValid) Then
                    Return executor
                End If
                executor = New WorkflowExecutor(key)
                If (workflowInstance Is Nothing) Then
                    workflowInstance = New WorkflowInstance(key, Me)
                End If
                Me.InitializeExecutor(key, context, executor, workflowInstance)
                Try 
                    WorkflowTrace.Host.TraceInformation("WorkflowRuntime:: replacing unusable executor for key {0} with new one (hc: {1})", New Object() { key, executor.GetHashCode })
                    dictionary.Item(key) = executor
                    Me.RegisterExecutor(((Not context Is Nothing) AndAlso context.IsActivation), executor)
                Catch obj1 As Object
                    Dim executor2 As WorkflowExecutor
                    If (dictionary.TryGetValue(key, executor2) AndAlso Object.Equals(executor, executor2)) Then
                        dictionary.Remove(key)
                    End If
                    Throw
                End Try
            End SyncLock
            executor.Registered(((Not context Is Nothing) AndAlso context.IsActivation))
            Return executor
        End Function

        Private Shared Function OnActivityDefinitionResolve(ByVal sender As Object, ByVal e As ActivityResolveEventArgs) As Activity
            Dim serviceProvider As WorkflowRuntime = [TryCast](e.ServiceProvider,WorkflowRuntime)
            If (serviceProvider Is Nothing) Then
                serviceProvider = RuntimeEnvironment.CurrentRuntime
            End If
            If (serviceProvider Is Nothing) Then
                Return Nothing
            End If
            If (Not e.Type Is Nothing) Then
                Return serviceProvider._workflowDefinitionDispenser.GetRootActivity(e.Type, e.CreateNewDefinition, e.InitializeForRuntime)
            End If
            Return serviceProvider._workflowDefinitionDispenser.GetRootActivity(e.WorkflowMarkup, e.RulesMarkup, e.CreateNewDefinition, e.InitializeForRuntime)
        End Function

        Friend Sub OnIdle(ByVal executor As WorkflowExecutor)
            Try 
                WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "Received OnIdle Event for instance, {0}", New Object() { executor.InstanceId })
                Dim workflowInstance As WorkflowInstance = executor.WorkflowInstance
                If (Not Me.WorkflowIdled Is Nothing) Then
                    Me.WorkflowIdled.Invoke(Me, New WorkflowEventArgs(workflowInstance))
                End If
            Catch exception1 As Exception
                WorkflowTrace.Host.TraceEvent(TraceEventType.Warning, 0, "OnIdle Event for instance, {0} threw an exception", New Object() { executor.InstanceId })
                Throw
            End Try
        End Sub

        Friend Sub OnScheduleAborted(ByVal schedule As WorkflowExecutor)
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime:ScheduleAborted event raised for instance Id {0}", New Object() { schedule.InstanceId })
            Me._OnServiceEvent(schedule, True, Me.WorkflowAborted)
        End Sub

        Friend Sub OnScheduleCompleted(ByVal schedule As WorkflowExecutor, ByVal args As WorkflowCompletedEventArgs)
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime:ScheduleCompleted event raised for instance Id {0}", New Object() { schedule.InstanceId })
            Try 
                If (Not Me.WorkflowCompleted Is Nothing) Then
                    Me.WorkflowCompleted.Invoke(Me, args)
                End If
            Catch exception1 As Exception
                WorkflowTrace.Host.TraceEvent(TraceEventType.Error, 0, "WorkflowRuntime:OnScheduleCompleted Event threw an exception.")
                Throw
            Finally
                Me._unRegister(schedule)
            End Try
        End Sub

        Friend Sub OnScheduleDynamicallyChanged(ByVal schedule As WorkflowExecutor)
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime:ScheduleDynamicallyChanged event raised for instance Id {0}", New Object() { schedule.InstanceId })
            Me._OnServiceEvent(schedule, False, Me.WorkflowDynamicallyChanged)
        End Sub

        Friend Sub OnScheduleLoaded(ByVal schedule As WorkflowExecutor)
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime:ScheduleLoaded event raised for instance Id {0}", New Object() { schedule.InstanceId })
            Me._OnServiceEvent(schedule, False, Me.WorkflowLoaded)
        End Sub

        Friend Sub OnSchedulePersisted(ByVal schedule As WorkflowExecutor)
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime:SchedulePersisted event raised for instance Id {0}", New Object() { schedule.InstanceId })
            Me._OnServiceEvent(schedule, False, Me.WorkflowPersisted)
        End Sub

        Friend Sub OnScheduleResumed(ByVal schedule As WorkflowExecutor)
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime:ScheduleResumed event raised for instance Id {0}", New Object() { schedule.InstanceId })
            Me._OnServiceEvent(schedule, False, Me.WorkflowResumed)
        End Sub

        Friend Sub OnScheduleSuspended(ByVal schedule As WorkflowExecutor, ByVal args As WorkflowSuspendedEventArgs)
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime:ScheduleSuspension event raised for instance Id {0}", New Object() { schedule.InstanceId })
            Try 
                If (Not Me.WorkflowSuspended Is Nothing) Then
                    Me.WorkflowSuspended.Invoke(Me, args)
                End If
            Catch exception1 As Exception
                WorkflowTrace.Host.TraceEvent(TraceEventType.Error, 0, "WorkflowRuntime:OnScheduleSuspended Event threw an exception.")
                Throw
            End Try
        End Sub

        Friend Sub OnScheduleTerminated(ByVal schedule As WorkflowExecutor, ByVal args As WorkflowTerminatedEventArgs)
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime:ScheduleTermination event raised for instance Id {0}", New Object() { schedule.InstanceId })
            Try 
                If (Not Me.WorkflowTerminated Is Nothing) Then
                    Me.WorkflowTerminated.Invoke(Me, args)
                End If
            Catch exception1 As Exception
                WorkflowTrace.Host.TraceEvent(TraceEventType.Error, 0, "WorkflowRuntime:OnScheduleTerminated Event threw an exception.")
                Throw
            Finally
                Me._unRegister(schedule)
            End Try
        End Sub

        Friend Sub OnScheduleUnloaded(ByVal schedule As WorkflowExecutor)
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime:ScheduleUnloaded event raised for instance Id {0}", New Object() { schedule.InstanceId })
            Me._OnServiceEvent(schedule, True, Me.WorkflowUnloaded)
        End Sub

        Private Shared Function OnWorkflowChangeActionsResolve(ByVal sender As Object, ByVal e As WorkflowChangeActionsResolveEventArgs) As ArrayList
            Dim list As ArrayList = Nothing
            Dim currentRuntime As WorkflowRuntime = RuntimeEnvironment.CurrentRuntime
            If (currentRuntime Is Nothing) Then
                Return list
            End If
            Dim serializer As New WorkflowMarkupSerializer
            Dim container As New ServiceContainer
            Dim service As ITypeProvider = currentRuntime.GetService([Of] ITypeProvider)
            If (Not service Is Nothing) Then
                container.AddService(GetType(ITypeProvider), service)
            ElseIf TypeOf sender Is Activity Then
                container.AddService(GetType(ITypeProvider), WorkflowRuntime.CreateTypeProvider([TryCast](sender,Activity)))
            End If
            Dim manager As New DesignerSerializationManager(container)
            [Using] manager.CreateSession
                [Using] reader As StringReader = New StringReader(e.WorkflowChangesMarkup)
                    [Using] reader2 As XmlReader = XmlReader.Create(reader)
                        Dim serializationManager As New WorkflowMarkupSerializationManager(manager)
                        Return [TryCast](serializer.Deserialize(serializationManager, reader2),ArrayList)
                    End [Using]
                End [Using]
            End [Using]
        End Function

        Private Sub PrivateInitialize(ByVal settings As WorkflowRuntimeSection)
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime: Created WorkflowRuntime {0}", New Object() { Me._uid })
            Me._workflowDefinitionDispenser = New WorkflowDefinitionDispenser(Me, If((Not settings Is Nothing), settings.ValidateOnCreate, True))
            Me.workflowExecutors = New FanOutOnKeyDictionary([Of] Guid, WorkflowExecutor)(((Environment.ProcessorCount * 4) - 1))
            Me._name = "WorkflowRuntime"
            If ((settings Is Nothing) OrElse settings.EnablePerformanceCounters) Then
                Me.PerformanceCounterManager = New PerformanceCounterManager
            End If
            If (Not settings Is Nothing) Then
                Me._name = settings.Name
                Me._configurationParameters = settings.CommonParameters
                Dim element As WorkflowRuntimeServiceElement
                For Each element In settings.Services
                    Me.AddServiceFromSettings(element)
                Next
            End If
            If Not Me.disableWorkflowDebugging.Enabled Then
                DebugController.InitializeProcessSecurity
                Me.debugController = New DebugController(Me, Me._name)
            End If
            SyncLock WorkflowRuntime._runtimesLock
                If Not WorkflowRuntime._runtimes.ContainsKey(Me._uid) Then
                    WorkflowRuntime._runtimes.Add(Me._uid, New WeakReference(Me))
                End If
            End SyncLock
        End Sub

        Friend Sub RaiseServicesExceptionNotHandledEvent(ByVal exception As Exception, ByVal instanceId As Guid)
            Me.VerifyInternalState
            WorkflowTrace.Host.TraceEvent(TraceEventType.Critical, 0, "WorkflowRuntime:ServicesExceptionNotHandled event raised for instance Id {0} {1}", New Object() { instanceId, exception.ToString })
            Dim servicesExceptionNotHandled As EventHandler([Of] ServicesExceptionNotHandledEventArgs) = Me.ServicesExceptionNotHandled
            If (Not servicesExceptionNotHandled Is Nothing) Then
                servicesExceptionNotHandled.Invoke(Me, New ServicesExceptionNotHandledEventArgs(exception, instanceId))
            End If
        End Sub

        Private Sub RegisterExecutor(ByVal isActivation As Boolean, ByVal executor As WorkflowExecutor)
            If isActivation Then
                executor.RegisterWithRuntime(Me)
            Else
                executor.ReRegisterWithRuntime(Me)
            End If
        End Sub

        Public Sub RemoveService(ByVal service As Object)
            If (service Is Nothing) Then
                Throw New ArgumentNullException("service")
            End If
            Me.VerifyInternalState
            [Using] New EventContext(New Object(0  - 1) {})
                SyncLock Me._startStopLock
                    SyncLock Me._servicesLock
                        If (Me._startedServices AndAlso Me.IsCoreService(service)) Then
                            Throw New InvalidOperationException(ExecutionStringManager.CantChangeImmutableContainer)
                        End If
                        If Not Me.GetAllServices(service.GetType).Contains(service) Then
                            Throw New InvalidOperationException(ExecutionStringManager.CantRemoveServiceNotContained)
                        End If
                        Dim list As List([Of] Object)
                        For Each list In Me._services.Values
                            If list.Contains(service) Then
                                list.Remove(service)
                            End If
                        Next
                    End SyncLock
                    Dim service2 As WorkflowRuntimeService = [TryCast](service,WorkflowRuntimeService)
                    If (Not service2 Is Nothing) Then
                        If Me._startedServices Then
                            service2.Stop
                        End If
                        service2.SetRuntime(Nothing)
                    End If
                End SyncLock
            End [Using]
        End Sub

        Friend Sub ReplaceWorkflowExecutor(ByVal instanceId As Guid, ByVal oldWorkflowExecutor As WorkflowExecutor, ByVal newWorkflowExecutor As WorkflowExecutor)
            Dim dictionary As Dictionary([Of] Guid, WorkflowExecutor) = Me.workflowExecutors.Item(instanceId)
            SyncLock dictionary
                oldWorkflowExecutor.IsInstanceValid = False
                WorkflowTrace.Host.TraceInformation("WorkflowRuntime:: replacing old executor for key {0} with new one", New Object() { instanceId })
                dictionary.Item(instanceId) = newWorkflowExecutor
            End SyncLock
        End Sub

        Public Sub StartRuntime()
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime: Starting WorkflowRuntime {0}", New Object() { Me._uid })
            SyncLock Me._startStopLock
                Me.VerifyInternalState
                If Not Me._startedServices Then
                    If (Me.GetAllServices(GetType(WorkflowCommitWorkBatchService)).Count = 0) Then
                        Me.AddServiceImpl(New DefaultWorkflowCommitWorkBatchService)
                    End If
                    If (Me.GetAllServices(GetType(WorkflowSchedulerService)).Count = 0) Then
                        Me.AddServiceImpl(New DefaultWorkflowSchedulerService)
                    End If
                    If (Me.GetAllServices(GetType(WorkflowLoaderService)).Count = 0) Then
                        Me.AddServiceImpl(New DefaultWorkflowLoaderService)
                    End If
                    If (Me.GetAllServices(GetType(WorkflowCommitWorkBatchService)).Count <> 1) Then
                        Throw New InvalidOperationException(String.Format(CultureInfo.CurrentCulture, ExecutionStringManager.InvalidWorkflowRuntimeConfiguration, New Object() { GetType(WorkflowCommitWorkBatchService).Name }))
                    End If
                    If (Me.GetAllServices(GetType(WorkflowSchedulerService)).Count <> 1) Then
                        Throw New InvalidOperationException(String.Format(CultureInfo.CurrentCulture, ExecutionStringManager.InvalidWorkflowRuntimeConfiguration, New Object() { GetType(WorkflowSchedulerService).Name }))
                    End If
                    If (Me.GetAllServices(GetType(WorkflowLoaderService)).Count <> 1) Then
                        Throw New InvalidOperationException(String.Format(CultureInfo.CurrentCulture, ExecutionStringManager.InvalidWorkflowRuntimeConfiguration, New Object() { GetType(WorkflowLoaderService).Name }))
                    End If
                    If (Me.GetAllServices(GetType(WorkflowPersistenceService)).Count > 1) Then
                        Throw New InvalidOperationException(String.Format(CultureInfo.CurrentCulture, ExecutionStringManager.InvalidWorkflowRuntimeConfiguration, New Object() { GetType(WorkflowPersistenceService).Name }))
                    End If
                    Me.isInstanceStarted = True
                    Me._trackingFactory.Initialize(Me)
                    If (Not Me.PerformanceCounterManager Is Nothing) Then
                        Me.PerformanceCounterManager.Initialize(Me)
                        Me.PerformanceCounterManager.SetInstanceName(Me.Name)
                    End If
                    Dim service As WorkflowRuntimeService
                    For Each service In Me.GetAllServices([Of] WorkflowRuntimeService)
                        service.Start
                    Next
                    Me._startedServices = True
                    [Using] New EventContext(New Object(0  - 1) {})
                        Dim started As EventHandler([Of] WorkflowRuntimeEventArgs) = Me.Started
                        If (Not started Is Nothing) Then
                            started.Invoke(Me, New WorkflowRuntimeEventArgs(Me.isInstanceStarted))
                        End If
                    End [Using]
                End If
            End SyncLock
            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime: Started WorkflowRuntime {0}", New Object() { Me._uid })
        End Sub

        Public Sub StopRuntime()
            Me.VerifyInternalState
            [Using] New EventContext(New Object(0  - 1) {})
                WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime: Stopping WorkflowRuntime {0}", New Object() { Me._uid })
                SyncLock Me._startStopLock
                    If Me._startedServices Then
                        Try 
                            Me.isInstanceStarted = False
                            If (Not Me.WorkflowPersistenceService Is Nothing) Then
                                Dim list As IList([Of] WorkflowExecutor) = Me.GetWorkflowExecutors
                                Do While ((Not list Is Nothing) AndAlso (list.Count > 0))
                                    Dim executor As WorkflowExecutor
                                    For Each executor In list
                                        If executor.IsInstanceValid Then
                                            Try 
                                                WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime: Calling Unload on instance {0} executor hc {1}", New Object() { executor.InstanceIdString, executor.GetHashCode })
                                                executor.Unload
                                                [Continue] For
                                            Catch exception1 As ExecutorLocksHeldException
                                                [Continue] For
                                            Catch exception2 As InvalidOperationException
                                                If executor.IsInstanceValid Then
                                                    Me.isInstanceStarted = True
                                                    Throw
                                                End If
                                                [Continue] For
                                            Catch obj1 As Object
                                                Me.isInstanceStarted = True
                                                Throw
                                            End Try
                                        End If
                                    Next
                                    list = Me.GetWorkflowExecutors
                                Loop
                            End If
                            Me.StopServices
                            Me._startedServices = False
                            WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime: Stopped WorkflowRuntime {0}", New Object() { Me._uid })
                            Me._trackingFactory.Uninitialize(Me)
                            If (Not Me.PerformanceCounterManager Is Nothing) Then
                                Me.PerformanceCounterManager.Uninitialize(Me)
                            End If
                            Dim stopped As EventHandler([Of] WorkflowRuntimeEventArgs) = Me.Stopped
                            If (Not stopped Is Nothing) Then
                                stopped.Invoke(Me, New WorkflowRuntimeEventArgs(Me.isInstanceStarted))
                            End If
                        Catch exception3 As Exception
                            WorkflowTrace.Host.TraceEvent(TraceEventType.Error, 0, "WorkflowRuntime::StartUnload Unexpected Exception")
                            Throw
                        Finally
                            Me.isInstanceStarted = False
                        End Try
                    End If
                End SyncLock
            End [Using]
        End Sub

        Private Sub StopServices()
            Dim service As WorkflowRuntimeService
            For Each service In Me.GetAllServices([Of] WorkflowRuntimeService)
                service.Stop
            Next
        End Sub

        Private Function TryRemoveWorkflowExecutor(ByVal instanceId As Guid, ByVal executor As WorkflowExecutor) As Boolean
            Dim dictionary As Dictionary([Of] Guid, WorkflowExecutor) = Me.workflowExecutors.Item(instanceId)
            SyncLock dictionary
                Dim executor2 As WorkflowExecutor
                If (dictionary.TryGetValue(instanceId, executor2) AndAlso Object.Equals(executor, executor2)) Then
                    WorkflowTrace.Host.TraceEvent(TraceEventType.Information, 0, "WorkflowRuntime::TryRemoveWorkflowExecutor, instance:{0}, hc:{1}", New Object() { executor.InstanceIdString, executor.GetHashCode })
                    Return dictionary.Remove(instanceId)
                End If
                Return False
            End SyncLock
        End Function

        Private Sub VerifyInternalState()
            If Me._disposed Then
                Throw New ObjectDisposedException("WorkflowRuntime")
            End If
        End Sub

        Private Sub WorkflowExecutionEvent(ByVal sender As Object, ByVal e As WorkflowExecutionEventArgs)
            If (sender Is Nothing) Then
                Throw New ArgumentNullException("sender")
            End If
            If Not GetType(WorkflowExecutor).IsInstanceOfType(sender) Then
                Throw New ArgumentException("sender")
            End If
            Dim schedule As WorkflowExecutor = DirectCast(sender, WorkflowExecutor)
            Select Case e.EventType
                Case WorkflowEventInternal.Created
                    If (Me.WorkflowCreated Is Nothing) Then
                        Exit Select
                    End If
                    Me.WorkflowCreated.Invoke(Me, New WorkflowEventArgs(schedule.WorkflowInstance))
                    Return
                Case WorkflowEventInternal.Completing, WorkflowEventInternal.SchedulerEmpty, WorkflowEventInternal.Suspending, WorkflowEventInternal.Resuming, WorkflowEventInternal.Persisting, WorkflowEventInternal.Unloading, WorkflowEventInternal.Exception, WorkflowEventInternal.Terminating, WorkflowEventInternal.Aborting
                    Exit Select
                Case WorkflowEventInternal.Completed
                    Me.OnScheduleCompleted(schedule, Me.CreateCompletedEventArgs(schedule))
                    Return
                Case WorkflowEventInternal.Idle
                    Me.OnIdle(schedule)
                    Return
                Case WorkflowEventInternal.Suspended
                    Dim args2 As WorkflowExecutionSuspendedEventArgs = DirectCast(e, WorkflowExecutionSuspendedEventArgs)
                    Me.OnScheduleSuspended(schedule, New WorkflowSuspendedEventArgs(schedule.WorkflowInstance, args2.Error))
                    Return
                Case WorkflowEventInternal.Resumed
                    Me.OnScheduleResumed(schedule)
                    Return
                Case WorkflowEventInternal.Persisted
                    Me.OnSchedulePersisted(schedule)
                    Return
                Case WorkflowEventInternal.Unloaded
                    Me.OnScheduleUnloaded(schedule)
                    Return
                Case WorkflowEventInternal.Loaded
                    Me.OnScheduleLoaded(schedule)
                    Return
                Case WorkflowEventInternal.Terminated
                    Dim args As WorkflowExecutionTerminatedEventArgs = DirectCast(e, WorkflowExecutionTerminatedEventArgs)
                    If (args.Exception Is Nothing) Then
                        Me.OnScheduleTerminated(schedule, New WorkflowTerminatedEventArgs(schedule.WorkflowInstance, args.Error))
                        Return
                    End If
                    Me.OnScheduleTerminated(schedule, New WorkflowTerminatedEventArgs(schedule.WorkflowInstance, args.Exception))
                    Return
                Case WorkflowEventInternal.Aborted
                    Me.OnScheduleAborted(schedule)
                    Return
                Case WorkflowEventInternal.DynamicChangeCommit
                    Me.DynamicUpdateCommit(schedule, DirectCast(e, DynamicUpdateEventArgs))
                    Exit Select
                Case WorkflowEventInternal.Started
                    If (Me.WorkflowStarted Is Nothing) Then
                        Exit Select
                    End If
                    Me.WorkflowStarted.Invoke(Me, New WorkflowEventArgs(schedule.WorkflowInstance))
                    Return
                Case Else
                    Return
            End Select
        End Sub

        Friend Sub WorkflowExecutorCreated(ByVal workflowExecutor As WorkflowExecutor, ByVal loaded As Boolean)
            Dim workflowExecutorInitializing As EventHandler([Of] WorkflowExecutorInitializingEventArgs) = Me.WorkflowExecutorInitializing
            If (Not workflowExecutorInitializing Is Nothing) Then
                workflowExecutorInitializing.Invoke(workflowExecutor, New WorkflowExecutorInitializingEventArgs(loaded))
            End If
            AddHandler workflowExecutor.WorkflowExecutionEvent, New EventHandler([Of] WorkflowExecutionEventArgs)(AddressOf Me.WorkflowExecutionEvent)
        End Sub


        ' Properties
        Friend ReadOnly Property CommonParameters As NameValueConfigurationCollection
            Get
                Return Me._configurationParameters
            End Get
        End Property

        Friend ReadOnly Property DefinitionDispenser As WorkflowDefinitionDispenser
            Get
                Return Me._workflowDefinitionDispenser
            End Get
        End Property

        Public ReadOnly Property IsStarted As Boolean
            Get
                Return Me._startedServices
            End Get
        End Property

        Friend ReadOnly Property IsZombie As Boolean
            Get
                Return Me._disposed
            End Get
        End Property

        Public Property Name As String
            Get
                Return Me._name
            End Get
            Set(ByVal value As String)
                SyncLock Me._startStopLock
                    If Me._startedServices Then
                        Throw New InvalidOperationException(ExecutionStringManager.CantChangeNameAfterStart)
                    End If
                    Me.VerifyInternalState
                    Me._name = value
                End SyncLock
            End Set
        End Property

        Property PerformanceCounterManager As PerformanceCounterManager
            Friend Get
                Return Me._performanceCounterManager
            End Get
            Private Set(ByVal value As PerformanceCounterManager)
                Me._performanceCounterManager = value
            End Set
        End Property

        Friend ReadOnly Property SchedulerService As WorkflowSchedulerService
            Get
                Return Me.GetService([Of] WorkflowSchedulerService)
            End Get
        End Property

        Friend ReadOnly Property TrackingListenerFactory As TrackingListenerFactory
            Get
                Return Me._trackingFactory
            End Get
        End Property

        Friend ReadOnly Property TrackingServices As List([Of] TrackingService)
            Get
                Dim list As New List([Of] TrackingService)
                Dim service As TrackingService
                For Each service In Me.GetAllServices(GetType(TrackingService))
                    list.Add(service)
                Next
                Return list
            End Get
        End Property

        Friend ReadOnly Property TransactionService As WorkflowCommitWorkBatchService
            Get
                Return DirectCast(Me.GetService(GetType(WorkflowCommitWorkBatchService)), WorkflowCommitWorkBatchService)
            End Get
        End Property

        Friend ReadOnly Property WorkflowPersistenceService As WorkflowPersistenceService
            Get
                Return DirectCast(Me.GetService(GetType(WorkflowPersistenceService)), WorkflowPersistenceService)
            End Get
        End Property


        ' Fields
        Private _configurationParameters As NameValueConfigurationCollection
        Private _disposed As Boolean
        Private _name As String
        Private _performanceCounterManager As PerformanceCounterManager
        Private Shared _runtimes As Dictionary([Of] Guid, WeakReference) = New Dictionary([Of] Guid, WeakReference)
        Private Shared _runtimesLock As Object = New Object
        Private _services As Dictionary([Of] Type, List([Of] Object))
        Private _servicesLock As Object
        Private _startedServices As Boolean
        Private _startStopLock As Object
        Private _trackingFactory As TrackingListenerFactory
        Private _uid As Guid
        Private _workflowDefinitionDispenser As WorkflowDefinitionDispenser
        Private debugController As DebugController
        Friend Const DefaultName As String = "WorkflowRuntime"
        Private disableWorkflowDebugging As BooleanSwitch
        Private isInstanceStarted As Boolean
        Private workflowExecutors As FanOutOnKeyDictionary([Of] Guid, WorkflowExecutor)

        ' Nested Types
        Friend NotInheritable Class EventContext
            Implements IDisposable
            ' Methods
            Public Sub New(ByVal ParamArray ignored As Object())
                If (Not EventContext.threadData Is Nothing) Then
                    Throw New InvalidOperationException(ExecutionStringManager.CannotCauseEventInEvent)
                End If
                EventContext.threadData = Me
            End Sub

            Private Sub System.IDisposable.Dispose() Implements IDisposable.Dispose
                EventContext.threadData = Nothing
            End Sub


            ' Fields
            <ThreadStatic> _
            Private Shared threadData As Object
        End Class

        Friend NotInheritable Class WorkflowExecutorInitializingEventArgs
            Inherits EventArgs
            ' Methods
            Friend Sub New(ByVal loading As Boolean)
                Me._loading = loading
            End Sub


            ' Properties
            Friend ReadOnly Property Loading As Boolean
                Get
                    Return Me._loading
                End Get
            End Property


            ' Fields
            Private _loading As Boolean
        End Class
    End Class
End Namespace

